package com.gjxx.buss.controller;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gjxx.buss.domain.bean.*;
import com.gjxx.buss.domain.TCarTeam;
import com.gjxx.buss.service.ITCarTeamService;
import com.gjxx.buss.service.TerminalMsgProcessDownService;
import com.gjxx.common.config.VideoPlayConfig;
import com.gjxx.common.constant.CacheConstants;
import com.gjxx.common.core.domain.AjaxResult;
import com.gjxx.common.core.domain.R;
import com.gjxx.common.core.redis.RedisCache;
import com.gjxx.common.tcp.HistoryVideoMsg;
import com.gjxx.common.tcp.ParamQueryMsg;
import com.gjxx.common.utils.DateUtils;
import com.gjxx.mongo.entity.CarDevOnlineStatus;
import com.gjxx.mongo.entity.TrajectoryPoint;
import com.gjxx.mongo.service.CarDevOnlineStatusService;
import com.gjxx.mongo.service.TrajectoryPointService;
import com.gjxx.netty.req.VideoPlayParam;
import com.gjxx.until.GaoDeMapUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.gjxx.common.annotation.Log;
import com.gjxx.common.core.controller.BaseController;
import com.gjxx.common.enums.BusinessType;
import com.gjxx.buss.domain.TCarDev;
import com.gjxx.buss.service.ITCarDevService;
import com.gjxx.common.utils.poi.ExcelUtil;
import com.gjxx.common.core.page.TableDataInfo;

/**
 * 车辆设备信息Controller
 *
 * @author gjxx
 * @date 2024-05-21
 */
@Slf4j
@RestController
@RequestMapping("/buss/carDev")
public class TCarDevController extends BaseController {
    @Autowired
    private ITCarDevService tCarDevService;
    @Autowired
    private ITCarTeamService tCarTeamService;
    @Autowired
    private CarDevOnlineStatusService carDevOnlineStatusService;
    @Autowired
    private TrajectoryPointService trajectoryPointService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private TerminalMsgProcessDownService terminalMsgProcessDownService;
    @Autowired
    private VideoPlayConfig videoPlayConfig;

    /**
     * 查询车辆设备信息列表
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:list')")
    @GetMapping("/list")
    public TableDataInfo list(TCarDev tCarDev) {
        startPage();
        List<TCarDev> list = tCarDevService.selectTCarDevList(tCarDev);
        for(TCarDev cDev : list){
            List<String> vedioChList = new ArrayList<>();
            String vedioCh = cDev.getVedioCh();
            if(vedioCh != null && !"".equals(vedioCh)){
                String[] vedioChBuff = vedioCh.split(",");
                vedioChList.addAll(Arrays.asList(vedioChBuff));
            }
            cDev.setVedioChList(vedioChList);
        }
        return getDataTable(list);
    }

    /**
     * 导出车辆设备信息列表
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:export')")
    @Log(title = "车辆设备信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, TCarDev tCarDev) {
        ExcelUtil<TCarDev> util = new ExcelUtil<>(TCarDev.class);

        List<TCarDev> list = tCarDevService.selectTCarDevList(tCarDev);
        util.exportExcel(response, list, "车辆设备信息数据");
    }

    /**
     * 获取车辆设备信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:query')")
    @GetMapping(value = "/{id}")
    public R<TCarDev> getInfo(@PathVariable("id") Long id) {
        TCarDev tCarDev = tCarDevService.getById(id);
        if(tCarDev != null){
            String vedioCh = tCarDev.getVedioCh();
            List<String> vedioChList = new ArrayList<>();
            if(vedioCh != null && !"".equals(vedioCh)){
                String[] vedioChBuff = vedioCh.split(",");
                vedioChList.addAll(Arrays.asList(vedioChBuff));
            }
            tCarDev.setVedioChList(vedioChList);
        }
        return R.ok(tCarDev);
    }

    /**
     * 新增车辆设备信息
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:add')")
    @Log(title = "车辆设备信息", businessType = BusinessType.INSERT)
    @PostMapping
    public R<Boolean> add(@RequestBody TCarDev tCarDev) {
        tCarDev.setCreateUser(getUsername());
        tCarDev.setUpdateUser(getUsername());
        long vehicleIdCount = tCarDevService.count(new QueryWrapper<TCarDev>().eq("vehicle_id", tCarDev.getVehicleId()));
        if(vehicleIdCount > 0){
            return R.fail("车辆标识已经存在！");
        }
        long simNoCount = tCarDevService.count(new QueryWrapper<TCarDev>().eq("sim_no", tCarDev.getSimNo()));
        if(simNoCount > 0){
            return R.fail("SIM卡号已经存在！");
        }
        StringBuilder vedioChBuff = new StringBuilder();
        List<String> vedioChList = tCarDev.getVedioChList();
        if (vedioChList != null) {
            Collections.sort(vedioChList);// 升序排列
            for (String vedioCh : tCarDev.getVedioChList()) {
                vedioChBuff.append(vedioCh).append(",");
            }
            tCarDev.setVedioCh(vedioChBuff.substring(0, vedioChBuff.length() - 1));
        }
        return R.ok(tCarDevService.save(tCarDev));
    }

    /**
     * 修改车辆设备信息
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:edit')")
    @Log(title = "车辆设备信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public R<Boolean> edit(@RequestBody TCarDev tCarDev) {
        tCarDev.setUpdateUser(getUsername());
        List<TCarDev> tCarDevList = tCarDevService.list(new QueryWrapper<TCarDev>().eq("vehicle_id", tCarDev.getVehicleId()));
        if(tCarDevList.size() > 0){
            if(!tCarDevList.get(0).getId().equals(tCarDev.getId())){
                return R.fail("车辆标识已经存在！");
            }
        }
        List<TCarDev> tCarDevList2 = tCarDevService.list(new QueryWrapper<TCarDev>().eq("sim_no", tCarDev.getSimNo()));
        if(tCarDevList2.size() > 0){
            if(!tCarDevList2.get(0).getId().equals(tCarDev.getId())){
                return R.fail("SIM卡号已经存在！");
            }
        }
        List<String> vedioChList = tCarDev.getVedioChList();
        StringBuilder vedioChBuff = new StringBuilder();
        if (vedioChList != null) {
            Collections.sort(vedioChList);// 升序排列
            for (String vedioCh : tCarDev.getVedioChList()) {
                vedioChBuff.append(vedioCh).append(",");
            }
            tCarDev.setVedioCh(vedioChBuff.substring(0, vedioChBuff.length() - 1));
        }
        return R.ok(tCarDevService.updateById(tCarDev));
    }

    /**
     * 删除车辆设备信息
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:remove')")
    @Log(title = "车辆设备信息", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public R<Boolean> remove(@PathVariable Long[] ids) {
        return R.ok(tCarDevService.removeBatchByIds(CollectionUtils.arrayToList(ids)));
    }

    /**
     * 查询所有车辆
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:getAllCarDev')")
    @GetMapping("/getAllCarDev")
    public AjaxResult getAllCarDev() {
        List<TCarDev>  tCarDevList = tCarDevService.list();
        return success(tCarDevList);
    }

    /**
     * 查询所有在线车辆信息
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:getOnlineCarDev')")
    @GetMapping("/getOnlineCarDev")
    public AjaxResult getOnlineCarDev() {
        List<CarDevOnlineStatus>  carDevOnlineStatusList = carDevOnlineStatusService.findAll();
        return success(carDevOnlineStatusList);
    }

    /**
     * 获取不带通道的车辆设备树列表
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:getCarDevTreeNoCHn')")
    @GetMapping("/getCarDevTreeNoCHn")
    public AjaxResult getCarDevTreeNoCHn(CarDevTree carDevTree) {
        List<CarDevTree> carDevTreeList = new ArrayList<>();
        if (carDevTree.getId() == null) {
            List<TCarTeam> tCarTeamList = tCarTeamService
                    .list(new QueryWrapper<TCarTeam>().eq("parent_id", 0));
            for (TCarTeam tCarTeam : tCarTeamList) {
                CarDevTree cDevTree = new CarDevTree();
                cDevTree.setId("carTeam"+tCarTeam.getId());
                List<String> tevSimNoList = tCarDevService.listChildSimNoByCarTeamId(tCarTeam.getId());
                cDevTree.setLabel(tCarTeam.getName() + "(" + tevSimNoList.size() + ")");
                if("Y".equals(tCarTeam.getWhetherCompany())){
                    cDevTree.setWhetherCompanyNode(true);
                }else {
                    cDevTree.setWhetherCompanyNode(false);
                }
                cDevTree.setWhetherCarDevNode(false);
                cDevTree.setWhetherCarDevChnNode(false);
                List<TCarTeam> teamList = tCarTeamService
                        .list(new QueryWrapper<TCarTeam>().eq("parent_id", cDevTree.getId()));
                List<TCarDev> devList = tCarDevService
                        .list(new QueryWrapper<TCarDev>().eq("car_team_id", cDevTree.getId()));
                if (teamList.size() == 0 && devList.size() == 0) {
                    cDevTree.setWhetherLastLevelNode(true);
                } else {
                    cDevTree.setWhetherLastLevelNode(false);
                }
                carDevTreeList.add(cDevTree);
            }
        } else {
            if (carDevTree.isWhetherCompanyNode()) {
                List<TCarDev> tCarDevList = tCarDevService
                        .list(new QueryWrapper<TCarDev>().eq("car_team_id", carDevTree.getId().substring(7)));
                AtomicInteger onlineStatusNum = new AtomicInteger();
                Collection<String> carDevKey = redisCache.keys(CacheConstants.CAR_DEV_ONLINE_STATUS+"*");
                carDevTreeList = tCarDevList.stream().map(tCarDev -> {
                    CarDevTree cDevTree = new CarDevTree();
                    cDevTree.setId(String.valueOf(tCarDev.getId()));
                    cDevTree.setLabel(tCarDev.getVehicleId());
                    boolean bool = carDevKey.contains(CacheConstants.CAR_DEV_ONLINE_STATUS + tCarDev.getSimNo());
                    if (bool) {
                        onlineStatusNum.getAndIncrement();
                        cDevTree.setCarDevStatus("01");
                    } else {
                        cDevTree.setCarDevStatus("02");
                    }
                    cDevTree.setWhetherCompanyNode(false);
                    cDevTree.setWhetherCarDevNode(true);
                    cDevTree.setWhetherCarDevChnNode(false);
                    cDevTree.setWhetherLastLevelNode(true);
                    return cDevTree;
                }).collect(Collectors.toList());
                if (carDevTreeList.size() > 0) {
                    carDevTreeList.get(0).setOnlineStatusCount("("+onlineStatusNum+"/"+tCarDevList.size()+")");
                }
            } else {
                List<TCarTeam> tCarTeamList = tCarTeamService
                        .list(new QueryWrapper<TCarTeam>().eq("parent_id", carDevTree.getId().substring(7)));
                for (TCarTeam tCarTeam : tCarTeamList) {
                    CarDevTree cDevTree = new CarDevTree();
                    cDevTree.setId("carTeam"+tCarTeam.getId());
                    List<String> tevSimNoList = tCarDevService.listChildSimNoByCarTeamId(tCarTeam.getId());
                    cDevTree.setLabel(tCarTeam.getName() + "(" + tevSimNoList.size() + ")");
                    if("Y".equals(tCarTeam.getWhetherCompany())){
                        cDevTree.setWhetherCompanyNode(true);
                    }else {
                        cDevTree.setWhetherCompanyNode(false);
                    }
                    cDevTree.setWhetherCarDevNode(false);
                    cDevTree.setWhetherCarDevChnNode(false);
                    List<TCarTeam> teamList = tCarTeamService
                            .list(new QueryWrapper<TCarTeam>().eq("parent_id", cDevTree.getId()));
                    List<TCarDev> devList = tCarDevService
                            .list(new QueryWrapper<TCarDev>().eq("car_team_id", cDevTree.getId()));
                    if (teamList.size() == 0 && devList.size() == 0) {
                        cDevTree.setWhetherLastLevelNode(true);
                    } else {
                        cDevTree.setWhetherLastLevelNode(false);
                    }
                    carDevTreeList.add(cDevTree);
                }
            }
        }
        return success(carDevTreeList);
    }

    /**
     * 根据车辆标识查询不带通道的车辆树
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:getCarDevTreeNoCHnByVehicleId')")
    @GetMapping("/getCarDevTreeNoCHnByVehicleId")
    public AjaxResult getCarDevTreeNoCHnByVehicleId(TCarDev tCarDev) {
        List<CarDevTree> carDevTreeList = new ArrayList<>();
        List<TCarDev> tCarDevList = tCarDevService
                .list(new QueryWrapper<TCarDev>().like("vehicle_id",tCarDev.getVehicleId()));
        for(TCarDev carDev:tCarDevList){
            CarDevTree cDevTree = new CarDevTree();
            cDevTree.setId(String.valueOf(carDev.getId()));
            cDevTree.setLabel(carDev.getVehicleId());
            CarDevOnlineStatus carDevOnlineStatus = carDevOnlineStatusService
                    .findCarDevOnlineStatusById(carDev.getSimNo());
            if (carDevOnlineStatus != null) {
                cDevTree.setCarDevStatus("01");
            } else {
                cDevTree.setCarDevStatus("02");
            }
            cDevTree.setWhetherCompanyNode(false);
            cDevTree.setWhetherCarDevNode(true);
            cDevTree.setWhetherLastLevelNode(true);
            carDevTreeList.add(cDevTree);
        }
        return success(carDevTreeList);
    }

    /**
     * 获取带通道的车辆设备树列表
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:getCarDevTree')")
    @GetMapping("/getCarDevTree")
    public AjaxResult getCarDevTree(CarDevTree carDevTree) {
        List<CarDevTree> carDevTreeList = new ArrayList<>();
        if (carDevTree.getId() == null) {
            List<TCarTeam> tCarTeamList = tCarTeamService
                    .list(new QueryWrapper<TCarTeam>().eq("parent_id", 0));
            for (TCarTeam tCarTeam : tCarTeamList) {
                CarDevTree cDevTree = new CarDevTree();
                cDevTree.setId("carTeam"+tCarTeam.getId());
                List<String> tevSimNoList = tCarDevService.listChildSimNoByCarTeamId(tCarTeam.getId());
                cDevTree.setLabel(tCarTeam.getName() + "(" + tevSimNoList.size() + ")");
                if("Y".equals(tCarTeam.getWhetherCompany())){
                    cDevTree.setWhetherCompanyNode(true);
                }else {
                    cDevTree.setWhetherCompanyNode(false);
                }
                cDevTree.setWhetherCarDevNode(false);
                cDevTree.setWhetherCarDevChnNode(false);
                List<TCarTeam> teamList = tCarTeamService
                        .list(new QueryWrapper<TCarTeam>().eq("parent_id", cDevTree.getId()));
                List<TCarDev> devList = tCarDevService
                        .list(new QueryWrapper<TCarDev>().eq("car_team_id", cDevTree.getId()));
                if (teamList.size() == 0 && devList.size() == 0) {
                    cDevTree.setWhetherLastLevelNode(true);
                } else {
                    cDevTree.setWhetherLastLevelNode(false);
                }
                carDevTreeList.add(cDevTree);
            }
        } else {
            if (carDevTree.isWhetherCompanyNode()) {
                List<TCarDev> tCarDevList = tCarDevService
                        .list(new QueryWrapper<TCarDev>().eq("car_team_id", carDevTree.getId().substring(7)));
                AtomicInteger onlineStatusNum = new AtomicInteger();
                Collection<String> carDevKey = redisCache.keys(CacheConstants.CAR_DEV_ONLINE_STATUS+"*");
                carDevTreeList = tCarDevList.stream().map(tCarDev -> {
                    CarDevTree cDevTree = new CarDevTree();
                    cDevTree.setId(String.valueOf(tCarDev.getId()));
                    cDevTree.setLabel(tCarDev.getVehicleId());
                    boolean bool = carDevKey.contains(CacheConstants.CAR_DEV_ONLINE_STATUS + tCarDev.getSimNo());
                    if (bool) {
                        onlineStatusNum.getAndIncrement();
                        cDevTree.setCarDevStatus("01");
                    } else {
                        cDevTree.setCarDevStatus("02");
                    }
                    cDevTree.setWhetherCompanyNode(false);
                    cDevTree.setWhetherCarDevNode(true);
                    cDevTree.setWhetherCarDevChnNode(false);
                    cDevTree.setWhetherLastLevelNode(false);
                    return cDevTree;
                }).collect(Collectors.toList());
                if (carDevTreeList.size() > 0) {
                    carDevTreeList.get(0).setOnlineStatusCount("("+onlineStatusNum+"/"+tCarDevList.size()+")");
                }
            } else {
                if (carDevTree.isWhetherCarDevNode()) {
                    TCarDev tCarDev = tCarDevService.getById(carDevTree.getId());
                    if (tCarDev != null) {
                        String vedioCh = tCarDev.getVedioCh();
                        List<String> vedioChList = new ArrayList<>();
                        if (vedioCh != null && !"".equals(vedioCh)) {
                            String[] vedioChBuff = vedioCh.split(",");
                            for (String vedioChStr : vedioChBuff) {
                                CarDevTree cDevTree = new CarDevTree();
                                cDevTree.setId(tCarDev.getVehicleId()+"-"+vedioChStr);
                                cDevTree.setCarDevId(tCarDev.getId());
                                cDevTree.setLabel("CH-" + vedioChStr);
                                boolean bool = redisCache.hasKey(CacheConstants.CAR_DEV_ONLINE_STATUS + tCarDev.getSimNo());
                                if (bool) {
                                    cDevTree.setCarDevStatus("01");
                                } else {
                                    cDevTree.setCarDevStatus("02");
                                }
                                cDevTree.setWhetherCompanyNode(false);
                                cDevTree.setWhetherCarDevNode(false);
                                cDevTree.setWhetherCarDevChnNode(true);
                                cDevTree.setWhetherLastLevelNode(true);
                                carDevTreeList.add(cDevTree);
                            }
                        }
                        tCarDev.setVedioChList(vedioChList);
                    }
                } else {
                    List<TCarTeam> tCarTeamList = tCarTeamService
                            .list(new QueryWrapper<TCarTeam>().eq("parent_id", carDevTree.getId().substring(7)));
                    for (TCarTeam tCarTeam : tCarTeamList) {
                        CarDevTree cDevTree = new CarDevTree();
                        cDevTree.setId("carTeam"+tCarTeam.getId());
                        List<String> tevSimNoList = tCarDevService.listChildSimNoByCarTeamId(tCarTeam.getId());
                        cDevTree.setLabel(tCarTeam.getName() + "(" + tevSimNoList.size() + ")");
                        if("Y".equals(tCarTeam.getWhetherCompany())){
                            cDevTree.setWhetherCompanyNode(true);
                        }else {
                            cDevTree.setWhetherCompanyNode(false);
                        }
                        cDevTree.setWhetherCarDevNode(false);
                        cDevTree.setWhetherCarDevChnNode(false);
                        List<TCarTeam> teamList = tCarTeamService
                                .list(new QueryWrapper<TCarTeam>().eq("parent_id", cDevTree.getId().substring(7)));
                        List<TCarDev> devList = tCarDevService
                                .list(new QueryWrapper<TCarDev>().eq("car_team_id", cDevTree.getId().substring(7)));
                        if (teamList.size() == 0 && devList.size() == 0) {
                            cDevTree.setWhetherLastLevelNode(true);
                        } else {
                            cDevTree.setWhetherLastLevelNode(false);
                        }
                        carDevTreeList.add(cDevTree);
                    }
                }
            }
        }
        return success(carDevTreeList);
    }


    /**
     * 根据车辆标识查询带通道的车辆树
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:getCarDevTreeByVehicleId')")
    @GetMapping("/getCarDevTreeByVehicleId")
    public AjaxResult getCarDevTreeByVehicleId(TCarDev tCarDev) {
        List<CarDevTree> carDevTreeList = new ArrayList<>();
        List<TCarDev> tCarDevList = tCarDevService
                .list(new QueryWrapper<TCarDev>().like("vehicle_id",tCarDev.getVehicleId()));
        for(TCarDev carDev:tCarDevList){
            CarDevTree cDevTree = new CarDevTree();
            cDevTree.setId(String.valueOf(carDev.getId()));
            cDevTree.setLabel(carDev.getVehicleId());
            CarDevOnlineStatus carDevOnlineStatus = carDevOnlineStatusService
                    .findCarDevOnlineStatusById(carDev.getSimNo());
            if (carDevOnlineStatus != null) {
                cDevTree.setCarDevStatus("01");
            } else {
                cDevTree.setCarDevStatus("02");
            }
            cDevTree.setWhetherCompanyNode(false);
            cDevTree.setWhetherCarDevNode(true);
            cDevTree.setWhetherLastLevelNode(false);
            carDevTreeList.add(cDevTree);
        }
        return success(carDevTreeList);
    }

    /**
     * 车辆设备信息和视频播放
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:carDevAndVedioPlay')")
    @GetMapping(value = "/carDevAndVedioPlay")
    public R<CarDevLocationAndVedioPlayBean> carDevAndVedioPlay(
            Long carDevId, String vedioChnNum,String streamType,String simNo) {
        CarDevLocationAndVedioPlayBean carDevLocationAndVedioPlayBean = new CarDevLocationAndVedioPlayBean();
        TCarDev tCarDev = tCarDevService.getById(carDevId);
        if(carDevId == null){
            tCarDev = tCarDevService.getOne(new QueryWrapper<TCarDev>().eq("sim_no",simNo));
        }
        if(tCarDev != null){
            CarDevOnlineStatus  carDevOnlineStatus = carDevOnlineStatusService.findCarDevOnlineStatusById(tCarDev.getSimNo());
            if(carDevOnlineStatus != null){
                StringBuilder buffer = new StringBuilder();
                buffer.append("在线,");
                if("01".equals(carDevOnlineStatus.getAccStatus())){
                    buffer.append("点火,");
                }else {
                    buffer.append("未点火,");
                }
                if("01".equals(carDevOnlineStatus.getWarningStatus())){
                    buffer.append("报警");
                }else {
                    buffer.append("未报警");
                }
                carDevLocationAndVedioPlayBean.setCarDevStatus(buffer.toString());
            }else {
                return R.fail("设备不在线");
            }
            vedioChnNum = vedioChnNum.split("-")[1];
            carDevLocationAndVedioPlayBean.setVedioChnNum(vedioChnNum);
            carDevLocationAndVedioPlayBean.setVehicleId(tCarDev.getVehicleId());
            carDevLocationAndVedioPlayBean.setVehicleNoColor(tCarDev.getVehicleNoColor());
            carDevLocationAndVedioPlayBean.setSimNo(tCarDev.getSimNo());
            TCarTeam tCarTeam = tCarTeamService.getById(tCarDev.getCarTeamId());
            if(tCarTeam != null){
                carDevLocationAndVedioPlayBean.setCarTeamName(tCarTeam.getName());
            }
            carDevLocationAndVedioPlayBean.setLongitude(carDevOnlineStatus.getLongitude());
            carDevLocationAndVedioPlayBean.setLatitude(carDevOnlineStatus.getLatitude());
            carDevLocationAndVedioPlayBean.setPosTime(carDevOnlineStatus.getPosTime());
            VideoPlayParam videoPlayParam = new VideoPlayParam();
            VideoPlayParam.Msg msg = new VideoPlayParam.Msg();
            videoPlayParam.setPlateNo(tCarDev.getVehicleId());
            videoPlayParam.setPlateColor(Integer.parseInt(tCarDev.getVehicleNoColor()));
            videoPlayParam.setMobileNumber(tCarDev.getSimNo());
            String videoPlayPhone = tCarDev.getSimNo();
            if(tCarDev.getSimNo().length() < 12){
                videoPlayPhone = "0"+tCarDev.getSimNo();
            }
            msg.setLogicalChn(Integer.parseInt(vedioChnNum));//通道
            msg.setDataType(0);//0：音视频，1：视频，2：双向对讲，3：监听，4：中心广播，5：透传
            msg.setStreamType(Integer.parseInt(streamType));//0：主码流，1：子码流
            msg.setSinkIP(videoPlayConfig.getSinkIP());
            msg.setSinkPort(Integer.parseInt(videoPlayConfig.getSinkPort()));
            msg.setCtrlCmd(0);
            msg.setCloseAVType(0);
            msg.setChangeStreamType(0);
            msg.setLossRate(0);
            msg.setResourceType(0);
            msg.setStorageType(0);
            msg.setReplayType(0);
            msg.setMultiples(0);
            videoPlayParam.setMsg(msg);
            R<String> stringR  = terminalMsgProcessDownService.realPlayRequest(videoPlayParam);
            if(R.isError(stringR)){
                return R.fail(stringR.getMsg());
            }
            String locationAddress = "";
            try {
                locationAddress = GaoDeMapUtil.getLocationFromCoordinates(carDevOnlineStatus.getLongitude(),carDevOnlineStatus.getLatitude());
            }catch (Exception e){
                e.printStackTrace();
                log.error("经纬度转换位置信息失败");
            }
            carDevLocationAndVedioPlayBean.setLocationAddress(locationAddress);
            String playUrl = "/video/" + videoPlayPhone+"-"+vedioChnNum;
            carDevLocationAndVedioPlayBean.setPlayRelativeUrl(playUrl);
            carDevLocationAndVedioPlayBean.setSinkIP(videoPlayConfig.getSinkIP());
            carDevLocationAndVedioPlayBean.setSinkPlayPort(videoPlayConfig.getSinkPlayPort());
            carDevLocationAndVedioPlayBean.setSinkPlayIP(videoPlayConfig.getSinkPlayIP());
            carDevLocationAndVedioPlayBean.setSinkPlayTwoPort(videoPlayConfig.getSinkPlayTwoPort());
            carDevLocationAndVedioPlayBean.setSinkPlayThreePort(videoPlayConfig.getSinkPlayThreePort());
            carDevLocationAndVedioPlayBean.setSinkPlayFourPort(videoPlayConfig.getSinkPlayFourPort());
            carDevLocationAndVedioPlayBean.setSinkPlayFivePort(videoPlayConfig.getSinkPlayFivePort());
        }else{
            return R.fail("设备不存在");
        }
        return R.ok(carDevLocationAndVedioPlayBean);
    }
    /**
     * 历史视频列表查询
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:historyVedioQuery')")
    @PostMapping(value = "/historyVedioQuery")
    public R<HistoryVideoMsg> historyVedioQuery(
            String selectCarDevId, String selectCarDevChn, String startTime, String endTime) throws ParseException {
        TCarDev tCarDev = tCarDevService.getById(selectCarDevId);
        if(tCarDev != null) {
            CarDevOnlineStatus carDevOnlineStatus = carDevOnlineStatusService.findCarDevOnlineStatusById(tCarDev.getSimNo());
            if(carDevOnlineStatus == null) {
                return R.fail("设备不在线");
            }
            Date startTimeDate = DateUtils.parseDate(startTime, DateUtils.YYYYMMDDHHMMSS);
            Date endTimeDate = DateUtils.parseDate(endTime, DateUtils.YYYYMMDDHHMMSS);
            boolean samedate = DateUtils.isSameDay(startTimeDate, endTimeDate);  //判断是否为同一天
            if(!samedate){
                return R.fail("开始和结束时间必须为同一天！");
            }
            String startTimeStr = DateUtils.parseDateToStr("yyMMddHHmmss",startTimeDate);
            String entTimeStr = DateUtils.parseDateToStr("yyMMddHHmmss",endTimeDate);
            selectCarDevChn = selectCarDevChn.split("-")[1];
            return terminalMsgProcessDownService.historyVideo(selectCarDevChn,tCarDev.getSimNo(),startTimeStr,entTimeStr);
        }else {
            return R.fail("设备不存在");
        }
    }
    /**
     * 历史视频播放
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:historyVedioPlay')")
    @PostMapping(value = "/historyVedioPlay")
    public R<VideoRtmpParamReturn> historyVedioPlay(
            String phone, String videoChn, String beginTime, String endTime) throws ParseException {
        List<TCarDev> tCarDevList = tCarDevService.list(new QueryWrapper<TCarDev>().eq("sim_no", phone));
        if(tCarDevList.size() <= 0){
            return R.fail("设备不存在");
        }else {
            CarDevOnlineStatus carDevOnlineStatus = carDevOnlineStatusService.findCarDevOnlineStatusById(phone);
            if(carDevOnlineStatus == null) {
                return R.fail("设备不在线");
            }
            TCarDev tCarDev = tCarDevList.get(0);
            VideoParamBean videoParam = new VideoParamBean();
            VideoParamBean.Msg videoPlayParamMsg = new VideoParamBean.Msg();
            videoParam.setVehicleId(tCarDev.getVehicleId());
            videoParam.setVehicleNoColor(Integer.parseInt(tCarDev.getVehicleNoColor()));
            videoParam.setMobileNumber(phone);
            videoPlayParamMsg.setLogicalChn(Integer.parseInt(videoChn));//通道
            videoPlayParamMsg.setResourceType(0);//音视频资源类型
            videoPlayParamMsg.setStreamType(1);//0：主码流，1：子码流
            videoPlayParamMsg.setStorageType(0);//存储器类型
            videoPlayParamMsg.setReplayType(0);//回放模式 0：正常回放；1：快进回放；2：关键帧快退回放；3：关键帧播放；4、单帧上传；
            videoPlayParamMsg.setMultiples(0);//快进或快退倍数
            videoPlayParamMsg.setBeginTime(beginTime);//开始时间
            videoPlayParamMsg.setEndTime(endTime);//结束时间
            videoPlayParamMsg.setSinkIP(videoPlayConfig.getSinkIP());
            videoPlayParamMsg.setSinkPort(Integer.parseInt(videoPlayConfig.getSinkPort()));
            videoParam.setMsg(videoPlayParamMsg);
            log.info("向终端下发远程录像回放请求:{}", JSON.toJSONString(videoParam, JSONWriter.Feature.PrettyFormat));
            return terminalMsgProcessDownService.playbackRequest(videoParam);
        }
    }

    /**
     * 向终端下发远程录像回放控制
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:historyVedioControl')")
    @PostMapping(value = "/historyVedioControl")
    public R<String> historyVedioControl(
            String phone, String videoChn, String ctrlCmd) {
        List<TCarDev> tCarDevList = tCarDevService.list(new QueryWrapper<TCarDev>().eq("sim_no", phone));
        if(tCarDevList.size() > 0){
            TCarDev tCarDev = tCarDevList.get(0);
            CarDevOnlineStatus  carDevOnlineStatus = carDevOnlineStatusService.findCarDevOnlineStatusById(phone);
            if(carDevOnlineStatus != null){
                VideoPlayParam videoPlayParam = new VideoPlayParam();
                videoPlayParam.setPlateNo(tCarDev.getVehicleId());
                videoPlayParam.setPlateColor(Integer.parseInt(tCarDev.getVehicleNoColor()));
                videoPlayParam.setMobileNumber(phone);
                VideoPlayParam.Msg msg = new VideoPlayParam.Msg();
                msg.setLogicalChn(Integer.parseInt(videoChn));
                msg.setCtrlCmd(Integer.parseInt(ctrlCmd));
                msg.setCloseAVType(0);
                msg.setChangeStreamType(0);
                videoPlayParam.setMsg(msg);
                R<String> stringR  = terminalMsgProcessDownService.playbackControl(videoPlayParam);
                if(R.isError(stringR)){
                    return R.fail(stringR.getMsg());
                }
            }else {
                return R.fail("设备不在线");
            }
        }else{
            return R.fail("设备不存在");
        }
        return R.ok("OK");
    }

    /**
     * 发送车辆实时位置查询命令
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:carDevLocationQuery')")
    @GetMapping(value = "/carDevLocationQuery")
    public R<String> carDevLocationQuery(Long carDevId) {
        TCarDev tCarDev = tCarDevService.getById(carDevId);
        if(tCarDev != null){
            CarDevOnlineStatus  carDevOnlineStatus = carDevOnlineStatusService.findCarDevOnlineStatusById(tCarDev.getSimNo());
            if(carDevOnlineStatus == null){
                return R.fail("设备不在线");
            }
            return terminalMsgProcessDownService.locationQuery(tCarDev.getSimNo());
        }else{
            return R.fail("设备不存在");
        }
    }

    /**
     * 查询车辆历史轨迹信息
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:trajectoryQuery')")
    @PostMapping(value = "/trajectoryQuery")
    public R<List<TraceVo>> trajectoryQuery(Long carDevId,String startTime,String endTime) {
        TCarDev tCarDev = tCarDevService.getById(carDevId);
        if(tCarDev != null){
            try {
                startTime = DateUtils.parseDateToStr("yyMMddHHmmss",DateUtils.parseDate(startTime, DateUtils.YYYYMMDDHHMMSS));
                startTime = tCarDev.getSimNo()+"_"+startTime;
                endTime = DateUtils.parseDateToStr("yyMMddHHmmss",DateUtils.parseDate(endTime, DateUtils.YYYYMMDDHHMMSS));
                endTime = tCarDev.getSimNo()+"_"+endTime;
                List<TrajectoryPoint> trajectoryPointList = trajectoryPointService.findAllByTime(startTime,endTime);
                List<TraceVo> traceVoList = new ArrayList<>();
                for(TrajectoryPoint trajectoryPoint: trajectoryPointList){
                    TraceVo traceVo = JSON.parseObject(trajectoryPoint.getTraceVoJson(), TraceVo.class);
                    BigDecimal b_longitude = new BigDecimal(traceVo.getLongitude());
                    b_longitude = b_longitude.divide(new BigDecimal("1000000"), 6, BigDecimal.ROUND_HALF_UP);
                    BigDecimal b_latitude = new BigDecimal(traceVo.getLatitude());
                    b_latitude = b_latitude.divide(new BigDecimal("1000000"), 6, BigDecimal.ROUND_HALF_UP);
                    traceVo.setLatitudeShow(b_latitude);
                    traceVo.setLongitudeShow(b_longitude);
                    traceVoList.add(traceVo);
                }
                traceVoList = GaoDeMapUtil.trajectoryRectify(traceVoList);
                return R.ok(traceVoList);
            }catch (Exception e){
                return R.fail("时间格式错误");
            }
        }else{
            return R.fail("设备不存在");
        }
    }

    /**
     * 发送设备拍照命令
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:photoScreen')")
    @GetMapping(value = "/photoScreen")
    public R<String> photoScreen(PhotoScreenDTO photoScreenDTO) {
        TCarDev tCarDev = tCarDevService.getById(photoScreenDTO.getSelectCarDevId());
        if(tCarDev != null){
            CarDevOnlineStatus  carDevOnlineStatus = carDevOnlineStatusService.findCarDevOnlineStatusById(tCarDev.getSimNo());
            if(carDevOnlineStatus == null){
                return R.fail("设备不在线");
            }
            photoScreenDTO.setSimNo(tCarDev.getSimNo());
            return terminalMsgProcessDownService.photoScreen(photoScreenDTO);
        }else{
            return R.fail("设备不存在");
        }
    }

    /**
     * 文本信息下发命令
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:textSend')")
    @GetMapping(value = "/textSend")
    public R<String> textSend(TextSendDTO textSendDTO) {
        TCarDev tCarDev = tCarDevService.getById(textSendDTO.getSelectCarDevId());
        if(tCarDev != null){
            CarDevOnlineStatus  carDevOnlineStatus = carDevOnlineStatusService.findCarDevOnlineStatusById(tCarDev.getSimNo());
            if(carDevOnlineStatus == null){
                return R.fail("设备不在线");
            }
            textSendDTO.setSimNo(tCarDev.getSimNo());
            return terminalMsgProcessDownService.textSend(textSendDTO);
        }else{
            return R.fail("设备不存在");
        }
    }

    /**
     * 设备参数查询命令
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:paramSelect')")
    @GetMapping(value = "/paramSelect")
    public R<ParamSelectVO> paramSelect(ParamSelectDTO paramSelectDTO) {
        TCarDev tCarDev = tCarDevService.getById(paramSelectDTO.getSelectCarDevId());
        if(tCarDev != null){
            CarDevOnlineStatus  carDevOnlineStatus = carDevOnlineStatusService.findCarDevOnlineStatusById(tCarDev.getSimNo());
            if(carDevOnlineStatus == null){
                return R.fail("设备不在线");
            }
            paramSelectDTO.setSimNo(tCarDev.getSimNo());
            return terminalMsgProcessDownService.paramSelect(paramSelectDTO);
        }else{
            return R.fail("设备不存在");
        }
    }

    /**
     * 设备参数设置命令
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:paramSet')")
    @GetMapping(value = "/paramSet")
    public R<String> paramSet(ParamSetDTO paramSetDTO) {
        TCarDev tCarDev = tCarDevService.getById(paramSetDTO.getSelectCarDevId());
        if(tCarDev != null){
            CarDevOnlineStatus  carDevOnlineStatus = carDevOnlineStatusService.findCarDevOnlineStatusById(tCarDev.getSimNo());
            if(carDevOnlineStatus == null){
                return R.fail("设备不在线");
            }
            paramSetDTO.setSimNo(tCarDev.getSimNo());
            return terminalMsgProcessDownService.paramSet(paramSetDTO);
        }else{
            return R.fail("设备不存在");
        }
    }

    /**
     * 电话回拨命令
     */
    @PreAuthorize("@ss.hasPermi('buss:carDev:photoScreen')")
    @GetMapping(value = "/phoneCar")
    public R<String> phoneCar(PhoneCarDTO phoneCarDTO) {
        TCarDev tCarDev = tCarDevService.getById(phoneCarDTO.getSelectCarDevId());
        if(tCarDev != null){
            CarDevOnlineStatus  carDevOnlineStatus = carDevOnlineStatusService.findCarDevOnlineStatusById(tCarDev.getSimNo());
            if(carDevOnlineStatus == null){
                return R.fail("设备不在线");
            }
            phoneCarDTO.setSimNo(tCarDev.getSimNo());
            return terminalMsgProcessDownService.phoneCar(phoneCarDTO);
        }else{
            return R.fail("设备不存在");
        }
    }

}
